﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Runtime.Serialization;
using zijian666.SuperConvert.Interface;

//using System.Runtime.Remoting;

namespace zijian666.SuperConvert.Dynamic
{
    /// <summary>
    /// 基于 <seealso cref="IList" /> 的动态类型
    /// </summary>
    internal class
        DynamicList : DynamicObjectBase<IList>, IList, IObjectReference //, IObjectHandle, ICustomTypeProvider
    {
        private static readonly IEnumerable<string> _dynamicMemberNames =
            new List<string> { "Count", "Length" }.AsReadOnly();

        public DynamicList(IList value, IConvertSettings convertSettings)
            : base(value, convertSettings)
        {
            if (value is null)
            {
                throw new ArgumentNullException(nameof(value));
            }
        }

        public override bool IsReadOnly => Value.IsReadOnly;


        int IList.Add(object value) => Value.Add(value);

        void IList.Clear() => Value.Clear();

        bool IList.Contains(object value) => Value.Contains(value);

        int IList.IndexOf(object value) => Value.IndexOf(value);

        void IList.Insert(int index, object value) => Value.Insert(index, value);

        bool IList.IsFixedSize => Value.IsFixedSize;

        void IList.Remove(object value) => Value.Remove(value);

        void IList.RemoveAt(int index) => Value.RemoveAt(index);

        object IList.this[int index]
        {
            get
            {
                if ((index >= 0) && (index < Value.Count))
                {
                    return WrapToDynamic(Value[index]);
                }

                return DynamicPrimitive.Null;
            }
            set { Value[index] = value; }
        }

        void ICollection.CopyTo(Array array, int index) => Value.CopyTo(array, index);

        int ICollection.Count => Value.Count;

        bool ICollection.IsSynchronized => Value.IsSynchronized;

        object ICollection.SyncRoot => Value;

        IEnumerator IEnumerable.GetEnumerator()
        {
            foreach (var item in Value)
            {
                if (item == null)
                {
                    yield return DynamicPrimitive.Null;
                }

                yield return WrapToDynamic(item);
            }
        }

        /// <summary>
        /// 返回所有动态成员名称的枚举。
        /// </summary>
        /// <returns> 一个包含动态成员名称的序列。 </returns>
        public override IEnumerable<string> GetDynamicMemberNames() => _dynamicMemberNames;

        public override bool TryConvert(ConvertBinder binder, out object result)
        {
            if ((Value.Count == 1) && TryChangeType(Value[0], binder.ReturnType, out result))
            {
                return true;
            }
            return TryChangeType(Value, binder.ReturnType, out result);
        }

        protected override object this[int index]
        {
            get => Value[index];
            set => Value[index] = value;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if ("count".Equals(binder.Name, StringComparison.OrdinalIgnoreCase)
                || "length".Equals(binder.Name, StringComparison.OrdinalIgnoreCase))
            {
                result = Value.Count;
                return true;
            }

            result = null;
            return false;
        }
    }
}
